package com.coollang.smartbra.views;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by jeanboy on 2016/10/17.
 */

public class RadarView extends View {

    private final static String TAG = "gzw";

    private List<RadarData> dataList;

    private int count = 6;//雷达网圈数
    private float angle;//多边形弧度
    private float radius;
    private float maxValue = 100f;
    private Paint mainPaint;//雷达区画笔
    private Paint valuePaint;//数据区画笔
    private Paint textPaint;//文本画笔

    private int mainColor = 0x8CFFFFFF;//雷达区颜色
    private int valueColor = 0x8CFFFFFF;//数据区颜色
    private int textColor = 0xFFFFFFFF;//文本颜色

    private float mainLineWidth = 0.5f;//雷达网线宽度dp
    private float valueLineWidth = 1f;//数据区边宽度dp
    private float valuePointRadius = 1.5f;//数据区圆点半径dp
    private float textSize = 13f;//字体大小sp

    private Context mContext;

    /**
     * 存储所有文字的坐标点
     */
    private List<Point> mScorePoints;

    private int mWidth, mHeight;
    private GestureDetector mGestureDetector;

    public RadarView(Context context) {
        this(context, null);
    }

    public RadarView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RadarView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;

        mGestureDetector = new GestureDetector(context, new RadarView.GestureListener());
        mGestureDetector.setIsLongpressEnabled(false);

        setup();
    }

    private void setup() {
        mainPaint = new Paint();
        mainPaint.setAntiAlias(true);
        mainPaint.setColor(mainColor);
        mainPaint.setStyle(Paint.Style.STROKE);

        valuePaint = new Paint();
        valuePaint.setAntiAlias(true);
        valuePaint.setColor(valueColor);
        valuePaint.setStyle(Paint.Style.FILL_AND_STROKE);

        textPaint = new Paint();
        textPaint.setAntiAlias(true);
        textPaint.setStyle(Paint.Style.FILL);
        textPaint.setColor(textColor);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        radius = Math.min(h, w) / 2 * 0.6f;
        mWidth = w;
        mHeight = h;
        postInvalidate();
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.translate(mWidth / 2, mHeight / 2);

        if (isDataListValid()) {
            drawSpiderweb(canvas);
            drawText(canvas);
            drawRegion(canvas);
        }
    }

    /**
     * 绘制蜘蛛网
     *
     * @param canvas
     */
    private void drawSpiderweb(Canvas canvas) {
        mainPaint.setStrokeWidth(dip2px(getContext(), mainLineWidth));
        Path webPath = new Path();
        Path linePath = new Path();
        float r = radius / (count - 1);//蜘蛛丝之间的间距
        for (int i = count - 1; i < count; i++) {
            float curR = r * i;//当前半径
            webPath.reset();
            for (int j = 0; j < count; j++) {
                float x = (float) (curR * Math.sin(angle / 2 + angle * j));
                float y = (float) (curR * Math.cos(angle / 2 + angle * j));
                if (j == 0) {
                    webPath.moveTo(x, y);
                } else {
                    webPath.lineTo(x, y);
                }
                if (i == count - 1) {//当绘制最后一环时绘制连接线
                    linePath.reset();
                    linePath.moveTo(0, 0);
                    linePath.lineTo(x, y);
                    canvas.drawPath(linePath, mainPaint);
                }
            }
            webPath.close();
            canvas.drawPath(webPath, mainPaint);
        }
    }

    /**
     * 绘制文本
     *
     * @param canvas
     */
    private void drawText(Canvas canvas) {
        textPaint.setTextSize(sp2px(getContext(), textSize));
        //textPaint.setUnderlineText(true);
        Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
        float fontHeight = fontMetrics.descent - fontMetrics.ascent;
        mScorePoints = new ArrayList();

        for (int i = 0; i < count; i++) {
            float x = (float) ((radius + fontHeight * 2) * Math.sin(angle / 2 + angle * i));
            float y = (float) ((radius + fontHeight * 2) * Math.cos(angle / 2 + angle * i));
            String title = dataList.get(i).getTitle();
            // 文本长度
            float dis = textPaint.measureText(title);
            canvas.drawText(title, x - dis / 2, y, textPaint);

            textPaint.setStrokeWidth(dip2px(mContext, 0.5f));
            float lineY = y + dip2px(mContext, 3);
            canvas.drawLine(x - dis / 2, lineY, x - dis / 2 + dis, lineY, textPaint);
            mScorePoints.add(new Point((int) (x - dis / 2), (int) y));
        }
    }

    /**
     * 绘制区域
     *
     * @param canvas
     */
    private void drawRegion(Canvas canvas) {
        valuePaint.setStrokeWidth(dip2px(getContext(), valueLineWidth));
        Path path = new Path();
        valuePaint.setAlpha(128);
        path.reset();

        for (int i = 0; i < count; i++) {
            double percent = dataList.get(i).getPercentage() / maxValue;
            float x = (float) (radius * Math.sin(angle / 2 + angle * i) * percent);
            float y = (float) (radius * Math.cos(angle / 2 + angle * i) * percent);
            if (i == 0) {
                path.moveTo(x, y);
            } else {
                path.lineTo(x, y);
            }

            //绘制小圆点
            canvas.drawCircle(x, y, dip2px(getContext(), valuePointRadius), valuePaint);
        }
        path.close();
        valuePaint.setStyle(Paint.Style.STROKE);
        canvas.drawPath(path, valuePaint);
        valuePaint.setAlpha(50);
        //绘制填充区域
        valuePaint.setStyle(Paint.Style.FILL_AND_STROKE);
        canvas.drawPath(path, valuePaint);
    }


    private boolean isDataListValid() {
        return dataList != null && dataList.size() >= 3;
    }


    public void setDataList(List<RadarData> dataList) {
        if (dataList == null || dataList.size() < 3) {
            throw new RuntimeException("The number of data can not be less than 3");
        } else {
            this.dataList = dataList;
            count = dataList.size();//圈数等于数据个数，默认为6
            angle = (float) (Math.PI * 2 / count);
            invalidate();
        }
    }


    public static int dip2px(Context context, float dipValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

    public static int sp2px(Context context, float spValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return mGestureDetector.onTouchEvent(event);
    }

    private class GestureListener extends GestureDetector.SimpleOnGestureListener {

        private GestureListener() {
        }

        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }

        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            onActionUpEvent(e);
            return true;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            return false;
        }
    }

    /**
     * 触摸点击事件
     *
     * @param e
     */
    private void onActionUpEvent(MotionEvent e) {

        float x = e.getX() - mWidth / 2;
        float y = e.getY() - mHeight / 2;

        if (validateTouch(x, y)) {
            // invalidate();
            if (mOnIndexClick != null) {
                mOnIndexClick.onClick(mCurrentIndex);
            }
        }
    }

    private int mCurrentIndex;
    private OnIndexClick mOnIndexClick;

    private boolean validateTouch(float x, float y) {
        int size = mScorePoints.size();


        for (int i = 0; i < size; ++i) {

            // 首先判断x坐标
            float leftX = (float) (mScorePoints.get(i)).x - dip2px(mContext, 10.0F);
            float rightX = (float) (mScorePoints.get(i)).x + dip2px(mContext, 60.0F);

            if (x > leftX
                    && x < rightX) {


                // 其次判断y坐标
                float topY = (float) (mScorePoints.get(i)).y - dip2px(mContext, 8.0F) * 2.0F;
                float bottomY = (float) (mScorePoints.get(i)).y + dip2px(mContext, 8.0F) * 2.0F;

                //Log.i("gzw", "y: " + (y - mHeight / 2) + " topY: " + topY + " bottomY: " + bottomY);

                if (y > topY
                        && y < bottomY) {
                    this.mCurrentIndex = i;
                    return true;
                }
            }
        }
        return false;
    }


    public void setOnIndexClick(OnIndexClick l) {
        this.mOnIndexClick = l;
    }

    /**
     * 点击事件处理
     */
    public interface OnIndexClick {
        void onClick(int index);
    }
}
